package com.xltq.dao.impl;

import com.xltq.dao.ICartDao;
import com.xltq.entity.Cart;
import com.xltq.entity.Product;
import com.xltq.utils.C3P0Utils;
import netscape.security.UserDialogHelper;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;

import javax.servlet.jsp.PageContext;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class ICartDaoImpl implements ICartDao {
    //提供DBUtils工具类对象
    private QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
    @Override
    public Cart hasCat(int uid, int pid) throws Exception {
        //在cart是以类中是存在另外一个类的对象[商品信息实体类对象]
        //即想查出购物车数据和商品数据,就需要进行联合查询
        String sql = "select p.p_id as pid,p.t_id as tid,p.p_name as pname,p.p_time as ptime, p.p_image as pimage," +
                "p.p_price as pprice, p.p_state as pstate,p.p_info as pinfo,c.c_id as cid," +
                "c.u_id as uid,c.p_id as pid,c.c_count as ccount,c.c_num as cnum " +
                "from product p join cart c on p.p_id = c.p_id where c.u_id = ? and  c.p_id = ?";
        /*
         因为是一个多表联合查询所以得到结果集是一个Cart类中存在一个Product实体类
         在DBUtils工具类中,提供一个Handler  ---> MapHandler  返回查询数数据类型是-->map集合
         这个MapHandler用于获取结果集中第一行数据,并将其封装到一个map
         即 map中key是列类型(as pid),没有做别名操作这个列就是实际的列名
            map中value是列对应的数据
         ps: 代表列的key 是不区分大小写的
         */
        Map<String, Object> query = queryRunner.query(sql, new MapHandler(), uid, pid);
        //做判断
        if(Objects.isNull(query)){
            return  null;
        }
        //将数据存在到对应Cart和Product中
        //项目中有有一个叫做BeanUtils工具类型,这个工具类型可以将map中存储数据转换存储到实体类中
        Cart cart = new Cart();
        Product product = new Product();
        BeanUtils.populate(cart, query);
        BeanUtils.populate(product,query);
        //上面代码操作完毕相当于将数据存储在单个实体类中,但是cart实体类中是包含商品实体类(实体类信息)
        cart.setProduct(product);
        return cart;
    }

    @Override
    public void updateCart(Cart cart) throws Exception {
        String sql = "update cart set c_num = ?, c_count = ? where c_id = ?";
        queryRunner.update(sql,cart.getCnum(),cart.getCcount(),cart.getCid());
    }

    @Override
    public void insertCart(Cart cart) throws Exception {
        String sql = "insert into cart(u_id,p_id,c_num,c_count) value(?,?,?,?)";
        queryRunner.update(sql,cart.getUid(),cart.getPid(),cart.getCnum(),cart.getCcount());

    }

    @Override
    public List<Cart> selectCartByUid(int uid) throws Exception {
        String sql = "select p.p_id as pid,p.t_id as tid,p.p_name as pname,p.p_time as ptime, " +
                "p.p_image as pimage,p.p_price as pprice, p.p_state as pstate,p.p_info as pinfo," +
                "c.c_id as cid,c.u_id as uid,c.p_id as pid,c.c_count as ccount,c.c_num as cnum " +
                "from product p join cart c on p.p_id = c.p_id where c.u_id = ?";
        /*
        上面这个语句修改了条件之后,效果就冲单条数据变成多条件
        DBUtils工具类中 提供了处理多表联合查询返回结果集类型是  ---> MapListHandler()
        用于将结果集中每行数据转换为map集合(效果等同于MapHandler(对应是一条数据)),在将map添加到List集合进行存储
        即 就相当于现将查询出来一条数据 以列名为key   以列对应值为value 存储在一个map集合中
           但是现在这个查询语句可能产生多个map集合对象,DBUtils为了方便外界可以会计的处理多个map对象
           将map对象又转存到List集合中,即List集合存储的都是Map集合的对象,map集合中存储的是每一条数据内容
           相当于List集合中存储了多条查询出来的数据对象,外界只需要对List集合进行操作就可以获取到集合中存的map对象数据了
           即多表查询出来数据
         */
        List<Map<String, Object>> list = queryRunner.query(sql, new MapListHandler(), uid);
        if(Objects.isNull(list)){
            return null;
        }
        //将查询出来存在List集合中的map集合数据存到Cart购物车实体类中外界代码才可以操作
        List<Cart> carts= new ArrayList<>();
        //读取list集合冲存的map对象数据并存储在cart对象中并添加到carts集合中
        for (Map<String, Object> map : list){
            Cart cart = new Cart();
            Product product = new Product();
            BeanUtils.populate(cart, map);
            BeanUtils.populate(product,map);
            //上面代码操作完毕相当于将数据存储在单个实体类中,但是cart实体类中是包含商品实体类(实体类信息)
            cart.setProduct(product);
            //将单个cart对象存在list集合中
            carts.add(cart);

        }
        return carts;
    }

    @Override
    public void deleteCartByCid(int cid) throws Exception {
        String  sql = "delete from  cart where  c_id = ?";
        queryRunner.update(sql,cid);

    }

    @Override
    public void deleteCartByUid(int uid) throws Exception {
        String  sql = "delete from  cart where u_id = ?";
        queryRunner.update(sql,uid);

    }

    @Override
    public void updateByCid(BigDecimal count, BigDecimal cnumbig, int cid) throws Exception {
        String sql = "update  cart set c_num = ?,c_count = ? where c_id = ?";
        queryRunner.update(sql,cnumbig,count,cid);
    }
}
